package org.aspire.game;

import org.aspire.core.sys.GSystem;
import org.aspire.data.Renderable;
import org.aspire.data.Renderer;
import org.aspire.data.Updateable;
import org.aspire.math.geom.Dimension;
import org.aspire.math.geom.Point;
import org.aspire.math.geom.Rectangle;

/******************************************************************************
 * @author JPACarabuena
 *****************************************************************************/
public class Background extends Entity implements Updateable, Renderable {

	// ========================================================================
	// Constants
	// ========================================================================

	/**************************************************************************
	 * The default background usually used in constructing sprite.
	 *************************************************************************/
	private static Background DEFAULT_BACKGROUND;
	
	// ========================================================================
	// Static Methods
	// ========================================================================

	/**************************************************************************
	 * Returns the default background used by every newly created sprite.
	 * 
	 * @return the default background.
	 *************************************************************************/
	public static Background getDefaultBackground() {
		if(Background.DEFAULT_BACKGROUND == null) {
			Background.DEFAULT_BACKGROUND = new Background();
		}
		return Background.DEFAULT_BACKGROUND;
	}
	
	// ========================================================================
	// Fields
	// ========================================================================

	/**************************************************************************
	 * The view-port ( for screen clipping ).
	 *************************************************************************/
	private final Rectangle clip;
	
	// ========================================================================
	// Constructors
	// ========================================================================

	/**************************************************************************
	 * Construct a new background with the specified dimension positioned at
	 * the default location, the origin.
	 * 
	 * @param dimension the specified dimension.
	 *************************************************************************/
	public Background(Dimension dimension) {
		super(dimension, new Point());
		
		this.clip = new Rectangle(GSystem.SCREEN_RESOLUTION);
	}
	
	/**************************************************************************
	 * Construct a new background with the same dimension as the system screen
	 * resolution positioned at the default location, the origin.
	 *************************************************************************/
	public Background() {
		this(GSystem.SCREEN_RESOLUTION);
	}
	
	/**************************************************************************
	 * Construct a new background with the specified width and height 
	 * positioned at the default location, the origin.
	 * 
	 * @param width	the width of the background.
	 * @param height the height of the background.
	 *************************************************************************/
	public Background(int width, int height) {
		this(new Dimension(width, height));
	}
	
	// ========================================================================
	// Getters & Setters
	// ========================================================================

	public Rectangle getClip() {
		return this.clip;
	}
	
	/**************************************************************************
	 * Sets the dimension of the background to the specified width and height.
	 * 
	 * @param width	the new width.
	 * @param height the new height.
	 *************************************************************************/
	public void setSize(int width, int height) {
		super.setWidth(width);
		super.setHeight(height);
		
		this.setLocation(this.getX(), this.getY());
	}
	
	/**************************************************************************
	 * Sets the location of the background to the specified x and y 
	 * coordinates.
	 * 
	 * @param x	the new x-coordinate.
	 * @param y the new y-coordinate.
	 *************************************************************************/
	public void setLocation(double x, double y) {
		if(x > this.getWidth() - this.clip.getWidth()) {
			x = this.getWidth() - this.clip.getWidth();
		}
		
		if(y > this.getHeight() - this.clip.getHeight()) {
			y = this.getHeight() - this.clip.getHeight();
		}
		
		if(x < 0) {
			x = 0;
		}
		
		if(y < 0) {
			y = 0;
		}
		
		this.setX(x);
		this.setY(y);
	}
	
	public void setClip(Point location, Dimension dimension) {
		this.clip.setLocation(location);
		this.clip.setDimension(dimension);
	}
	
	// ========================================================================
	// Override Methods
	// ========================================================================

	@Override
	public void render(Renderer r) {
		
	}

	@Override
	public void update(long elapsedTime) {
		
	}
	
	// ========================================================================
	// Methods
	// ========================================================================

	/**************************************************************************
	 * Move the background location by the specified pixels.
	 * 
	 * @param dx	the specified pixel movement in x-axis.
	 * @param dy	the specified pixel movement in y-axis.
	 *************************************************************************/
	public void move(double dx, double dy) {
		this.setLocation(this.getX() + dx, this.getY() + dy);
	}
	
	public void setToCenter(Sprite sprite) {
		this.setToCenter(sprite.getWidth(), sprite.getHeight(), 
				sprite.getCenterX(), sprite.getCenterY());
	}
	
	public void setToCenter(Dimension dimension, Point location) {
		this.setToCenter(dimension.getHeightInt(), dimension.getWidthInt(),
				location.getX(), location.getY());
	}
	
	public void setToCenter(int width, int height, double x, double y) {
		this.setLocation(x + (width / 2) + (this.clip.getWidth() / 2), 
				y + (height / 2) + (this.clip.getHeight() / 2));
	}

	// ========================================================================
	// Inner & Anonymous Classes
	// ========================================================================
}